package com.cqupt.sendMes.interceptor;

import cn.hutool.core.util.ObjectUtil;
import com.cqupt.sendMes.enums.HttpStatusEnum;
import com.cqupt.sendMes.exception.BusinessException;
import com.cqupt.sendMes.utils.JwtUtil;
import com.cqupt.sendMes.utils.ThreadLocalUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.SignatureException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtil jwtUtil; // JWT 工具类，用于生成和验证 JWT

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //打日志，看看看请求的URL
        log.info("请求的URL: {}", request.getRequestURL());
        // 如果是OPTIONS请求，直接返回true
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            return true;
        }
        //过滤掉登陆接口
        if (request.getRequestURI().equals("/user/login")) {
            return true;
        }

        String tokenHash = request.getHeader("Authorization");

        if (tokenHash == null) {
            log.error("未携带token");
            throw new BusinessException(HttpStatusEnum.NO_LOGIN.getCode(), HttpStatusEnum.NO_LOGIN.getMessage());
        }

        try {
            String token = redisTemplate.opsForValue().get(tokenHash);
//            token = token.replace("Bearer ", "");
            if(ObjectUtil.isEmpty(token)){
                //没查到
                log.error("token不存在");
                throw new BusinessException(HttpStatusEnum.NO_LOGIN.getCode(), HttpStatusEnum.NO_LOGIN.getMessage());
            }
            if(!jwtUtil.isTokenValid(token)){
                //如果已过期
                log.error("token已过期");
                throw new BusinessException(HttpStatusEnum.LOGIN_EXPIRED.getCode(), HttpStatusEnum.LOGIN_EXPIRED.getMessage());
            }
            Claims claims =  jwtUtil.getClaimsFromToken(token);
            claims.put("tokenHash", tokenHash); // 将 tokenHash 添加到 claims 中，注销登录时使用
            ThreadLocalUtil.set(claims); // 将解析后的 JWT 存入 ThreadLocal 中
        } catch (SignatureException e) {
            log.error("处理token时发生异常");
            throw new BusinessException(HttpStatusEnum.UNKOWN_SYSTEM_ERROR.getCode(), HttpStatusEnum.UNKOWN_SYSTEM_ERROR.getMessage());
        }

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在请求结束后清除 ThreadLocal 中的数据
        ThreadLocalUtil.remove();
    }
}
